package com.seatatcc.stock.service.impl;

import com.seatatcc.stock.mapper.StockMapper;
import com.seatatcc.stock.service.StockService;
import io.seata.rm.tcc.api.BusinessActionContext;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

/****************************************************
 *
 * @author lbf
 * @date 2025/7/16 17:15
 ****************************************************/
@Service
public class StockServiceImpl implements StockService {

    @Autowired
    private StockMapper stockMapper;

    /**
     * tcc服务t（try）方法
     * 根据实际业务场景选择实际业务执行逻辑或者资源预留逻辑
     *
     * 在try方法中使用@Transational可以直接通过spring事务回滚关系型数据库中的操作，
     * 而非关系型数据库等中间件的回滚操作可以交给rollbackMethod方法处理。
     *
     * 使用context.getActionContext("params")便可以得到一阶段try中定义的参数，在二阶段对此参数进行业务回滚操作。
     *
     * 注意1：t(try) 方法不可以捕获异常（同理切面处理异常，异常需要抛出去），否则TCC将识别该操作为成功，二阶段直接执行commitMethod。
     * 注意2：TCC模式要开发者自行保证幂等和事务防悬挂
     */
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    @Override
    public void decrement() {

        //实际事务操作，或操作MQ、redis等
        stockMapper.decrement();
    }

    /**
     * tcc服务 confirm方法
     * 若一阶段采用资源预留，在二阶段确认时要提交预留的资源
     *
     * @param context 上下文
     * @return boolean
     */
    @Override
    public boolean commitTcc(BusinessActionContext context) {
        System.out.println("xid = " + context.getXid() + "提交成功");
        //todo 若一阶段资源预留，这里则要提交资源
        return true;
    }

    /**
     * tcc 服务 cancel方法
     *
     * @param context 上下文
     * @return boolean
     */
    @Override
    public boolean cancel(BusinessActionContext context) {
        //todo 这里写中间件、非关系型数据库的回滚操作
        System.out.println("please manually rollback this data" );
        return true;
    }
}
